#include "Time.h"
#include <string.h>
#include <iostream>

namespace BASE{
	std::string Time::FMT = "%Y-%m-%d %H:%M:%S";

	time_t Time::getNow(){
		return time(NULL);
	}

	int64_t Time::getMicroTime(){
		int64_t now = 0;
		struct timeval tv;
		gettimeofday(&tv, NULL);
		now = tv.tv_sec * 1000000 + tv.tv_usec;
		return now;
	}

	int64_t Time::getMillTime(){
		return Time::getMicroTime() / 1000;
	}

	size_t Time::getTimeStamp(time_t timestamp, char * buf, int size, bool needUsec, const std::string & fmt){
		if (buf == NULL || size == 0){
			return 0;
		}
		size_t pos = 0;
		size_t totalSize = pos;
		if (timestamp == 0){
			timeval tv;
			gettimeofday(&tv, NULL);
			struct tm t1;
			localtime_r(&tv.tv_sec, &t1);
			pos = strftime(buf, size, fmt.c_str(), &t1);
			totalSize = pos;
			if (needUsec){
				snprintf(buf + pos, size - pos, "%3.3ld", tv.tv_usec / 1000);
				totalSize += 3;
				pos += 3;
			}
		}else{
			struct tm t1;
			localtime_r(&timestamp, &t1);
			pos = strftime(buf, size, fmt.c_str(), &t1);
			totalSize = pos;
		}
		buf[pos] = '\0';
		return totalSize;
	}

	std::string Time::getDateText(time_t timestamp, const std::string & fmt){
		char buf[100] = {0};
		Time::getTimeStamp(timestamp, buf, sizeof(buf));
		return std::string(buf);
	}

	time_t Time::fromString(const std::string & timeTxt, const std::string & fmt){
		struct tm t1;
		memset(&t1, 0, sizeof(t1));
		char * result = strptime(timeTxt.c_str(), fmt.c_str(), &t1);
		if (NULL == result){
			return -1;
		}
		time_t val = mktime(&t1);
		return val;
	}

	std::string Time::toString(time_t time, const std::string & fmt){
		struct tm t1;
		localtime_r(&time, &t1);
		char buf[100] = {0};
		strftime(buf, sizeof(buf), fmt.c_str(), &t1);
		return std::string(buf);
	}

	bool Time::checkDay(time_t time1, time_t time2){
		struct tm t1,t2;
		localtime_r(&time1, &t1);
		localtime_r(&time2, &t2);
		//std::cout << time1 << "," <<  t1.tm_mday << "," << t2.tm_mday << std::endl;
		return t1.tm_mday == t2.tm_mday;
	}

	TimeCheck::TimeCheck(int32_t _timeOutMillSec):timeOutMillSec(_timeOutMillSec){
		lastCheckTime = Time::getMillTime();
	}

	void TimeCheck::setTimeOut(int32_t _timeOutMillSec){
		timeOutMillSec = _timeOutMillSec;
	}

	bool TimeCheck::isTimeOut(){
		int64_t now = Time::getMillTime();
		if (now - lastCheckTime >= timeOutMillSec){
			lastCheckTime = now;
			return true;
		}
		return false;
	}
}
